package vip.meeet.jdk.time;

import org.junit.jupiter.api.Test;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;

public class Jdk8Datetime {

    @Test
    public void time2SecMill() {
        System.out.println(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
        System.out.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
    }

    @Test
    public void instant(){
        Instant start = Instant.now();
        for(int i=0;i<10000;i++){
            //dosomething
        }
        Instant end = Instant.now();
        Duration duration = Duration.between(start,end);
        System.out.println(duration.toMillis());
    }

    @Test
    public void createLocalDate(){
        LocalDate.now();//今天
        LocalDate.of(2021, 1, 1);
        LocalDate.of(2021, Month.JANUARY, 1);
        LocalDate.parse("2021-01-01");
    }

    @Test
    public void compareLocalDate(){
        LocalDate now = LocalDate.now();
        LocalDate first = LocalDate.of(2021, 1, 1);
        System.out.println(now.isBefore(first));//now日期是不是早于first
        System.out.println(now.isAfter(first));//now日期是不是晚于first
        System.out.println(now.isEqual(first));//now和first是不是同一天
    }

    @Test
    public void otherLocalDate(){
        LocalDate now = LocalDate.now();
        now.toEpochDay();//当前日期时间戳对应的天
        now.withYear(2021);//指定年份
        now.until(LocalDate.now().plusDays(36));//计算2个日期的时间区间
        now.atStartOfDay();//一天的开始时间
        now.format(DateTimeFormatter.ISO_DATE_TIME);//格式化时间
    }

    @Test
    public void calcLocalDate(){
        LocalDate now = LocalDate.now();
        now.plusDays(7);//7天之后
        now.plusYears(1);//1年之后
        now.minusMonths(1);//1月之前
        now.minusWeeks(1);//1周之前
    }

    @Test
    public void temporalAdjusters(){
        LocalDate date = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
    }

    @Test
    public void localTime(){
        LocalTime now = LocalTime.now();
    }

    @Test
    public void zonedDateTime(){

    }

    @Test
    public void localDatetiem(){
        LocalDateTime now = LocalDateTime.now();
    }

    @Test
    public void datetimeFormatter(){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime date = LocalDateTime.now();
        System.out.println(formatter.format(date));
        System.out.println(DateTimeFormatter.ISO_LOCAL_DATE.format(date));
        System.out.println(DateTimeFormatter.ISO_LOCAL_TIME.format(date));
        System.out.println(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(date));
        System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).format(date));
        System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG).format(date));
    }

    @Test
    public void testPlus(){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate end = LocalDate.parse("2018-06-03", formatter);
        LocalDate localDate = end.plusYears(-1);
        String handleDate = localDate.format(formatter);
        System.out.println(handleDate);
    }

    @Test
    public void utc(){
//        LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        Instant instant = LocalDateTime.now().toInstant(ZoneOffset.of("+8"));
        LocalDateTime.now().toInstant(ZoneOffset.UTC);

        Long timestamp = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        LocalDateTime time2 =LocalDateTime.ofEpochSecond(timestamp/1000,0,ZoneOffset.ofHours(8));

        ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
        nowUTC.toLocalDateTime();
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt.toLocalTime());

        ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());

        ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));

        System.out.println(utcZoned.toLocalTime());
        LocalDateTime.now(Clock.systemUTC());
        LocalDateTime.now(ZoneOffset.UTC);
    }

    @Test
    public void utctime(){
        LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
        System.out.println(now);
        LocalDateTime now1 = LocalDateTime.now(ZoneOffset.UTC);
        System.out.println(now1);
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println(now2);
        System.out.println(now1.getHour()-1);
    }

    @Test
    public void utct(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC);
        int hour = localDateTime.getHour();
        System.out.println(hour);
        Date date;
        date = new Date(localDateTime.toEpochSecond(ZoneOffset.UTC) * 1000);
        System.out.println(sdf.format(date));
        date = new Date(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        System.out.println(sdf.format(date));
        date = new Date(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli());
        System.out.println(sdf.format(date));
    }

    @Test
    public void utct2(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC);
//        LocalDateTime localDateTime = LocalDateTime.now();
        OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.UTC);
        System.out.println(offsetDateTime.toZonedDateTime().format(DateTimeFormatter.ISO_DATE_TIME));
        int hour = localDateTime.getHour();
        System.out.println(hour);
        Date date;
        date = new Date(localDateTime.toEpochSecond(ZoneOffset.UTC) * 1000);
        System.out.println(sdf.format(date));
        date = new Date(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        System.out.println(sdf.format(date));
        date = new Date(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli());
        System.out.println(sdf.format(date));
    }

    @Test
    public void testDiff(){
        int year = 2019, month = 8;
        test19(year,month);
        test20(year,month);
    }

    private void test19(int year,int month){
        LocalDate firstDay = LocalDate.of(year, month, 1);
        int week = firstDay.getDayOfWeek().getValue();
        LocalDate start,end;
        if(week < 5) {
            start = firstDay.plusDays(-(2 + week));
        }else if(week == 5){
            start = firstDay;
        }else {//week > 5
            start = firstDay.plusDays(5 - week);
        }

        int lengthOfMonth = firstDay.lengthOfMonth();
        LocalDate lastDay = firstDay.plusDays(lengthOfMonth - 1);
        week = lastDay.getDayOfWeek().getValue();
        if(week > 4){
           end = lastDay.plusDays(11-week);
        }else if(week == 4){
            end = lastDay;
        }else{//week < 4
            end = lastDay.plusDays(4 - week);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String startDate = start.format(formatter);
        String endDate = end.format(formatter);
        System.out.println(startDate);
        System.out.println(endDate);
        System.out.println(end.toEpochDay() - start.toEpochDay());
    }

    private void test20(int year,int month){
        LocalDate firstDay = LocalDate.of(year, month, 1);
        int week = firstDay.getDayOfWeek().getValue();
        LocalDate start,end;
        if(week < 5) {
            start = firstDay.plusDays(-(2 + week));
        }else if(week == 5){
            start = firstDay;
        }else {//week > 5
            start = firstDay.plusDays(5 - week);
        }
        end = start.plusDays(34);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String startDate = start.format(formatter);
        String endDate = end.format(formatter);
        System.out.println(startDate);
        System.out.println(endDate);
        System.out.println(end.toEpochDay() - start.toEpochDay());
    }

    @Test
    public void chronoFieldTest(){
        LocalDate localDate = LocalDate.now();
        System.out.println(localDate.getLong(ChronoField.DAY_OF_YEAR));
        System.out.println(localDate.getLong(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH));
        System.out.println(localDate.getLong(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR));
        System.out.println(localDate.getLong(ChronoField.ALIGNED_WEEK_OF_MONTH));
        System.out.println(localDate.getLong(ChronoField.ERA));
        System.out.println(localDate.getLong(ChronoField.EPOCH_DAY));
//        System.out.println(localDate.getLong(ChronoField.MINUTE_OF_HOUR));
//        ChronoUnit
    }

    @Test
    public void test(){
        Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
//        LocalDateTime localDateTime = LocalDateTime.from(instant);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant,ZoneId.systemDefault());
        System.out.println(localDateTime.format(DateTimeFormatter.ISO_DATE_TIME));
    }

    @Test
    public void calc(){
        LocalDate end = LocalDate.of(2020, 1, 1);
        LocalDateTime localDateTime = end.atStartOfDay();
        System.out.println(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli());

    }
}
